API: gtk: Add gtk_widget_set_visual()
authorBenjamin Otte <otte@redhat.com>
Tue, 28 Sep 2010 16:56:34 +0000 (18:56 +0200)
committerBenjamin Otte <otte@redhat.com>
Tue, 28 Sep 2010 17:11:21 +0000 (19:11 +0200)
It turns out that the previous handling of just providing a way to set
visuals just on toplevels was not sufficient. In particular it
complicated the various implementations of the tray icon specification.
This patch reintroduces gtk_widget_set_visual() which behaves very
similar to GTK2's gtk_widget_set_colormap().

A future commit will remove the gtk_window_set_visual() function.

docs/reference/gtk/gtk3-sections.txt
gtk/gtk.symbols
gtk/gtkwidget.c
gtk/gtkwidget.h

index cdce8d71cabe8f75927ee36d5078d458634a2feb..01416e6ed7b1a9ad6cdbf44cb4ef6f365eb0c4d9 100644 (file)
@@ -4783,6 +4783,7 @@ gtk_widget_add_device_events
 gtk_widget_get_toplevel
 gtk_widget_get_ancestor
 gtk_widget_get_visual
+gtk_widget_set_visual
 gtk_widget_get_pointer
 gtk_widget_is_ancestor
 gtk_widget_translate_coordinates
index fd43fc7e26cda26db3279bffa84782e71560bb6f..e9b3eae3f05bb6edc50c68989f7cdc098d11281c 100644 (file)
@@ -4308,6 +4308,7 @@ gtk_widget_set_tooltip_markup
 gtk_widget_set_tooltip_text
 gtk_widget_set_tooltip_window
 gtk_widget_set_visible
+gtk_widget_set_visual
 gtk_widget_set_window
 gtk_widget_shape_combine_region
 gtk_widget_input_shape_combine_region
index 9001403d1c83adadb265b1193b24149ef571fa15..01aea78352c2c0a94f89b2a252afb37583e3eaba 100644 (file)
@@ -507,6 +507,7 @@ static GQuark               quark_mnemonic_labels = 0;
 static GQuark          quark_tooltip_markup = 0;
 static GQuark          quark_has_tooltip = 0;
 static GQuark          quark_tooltip_window = 0;
+static GQuark          quark_visual = 0;
 GParamSpecPool         *_gtk_widget_child_property_pool = NULL;
 GObjectNotifyContext   *_gtk_widget_child_property_notify_context = NULL;
 
@@ -619,6 +620,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
   quark_tooltip_markup = g_quark_from_static_string ("gtk-tooltip-markup");
   quark_has_tooltip = g_quark_from_static_string ("gtk-has-tooltip");
   quark_tooltip_window = g_quark_from_static_string ("gtk-tooltip-window");
+  quark_visual = g_quark_from_static_string ("gtk-widget-visual");
 
   style_property_spec_pool = g_param_spec_pool_new (FALSE);
   _gtk_widget_child_property_pool = g_param_spec_pool_new (TRUE);
@@ -8955,6 +8957,36 @@ gtk_widget_get_ancestor (GtkWidget *widget,
   return widget;
 }
 
+/**
+ * gtk_widget_set_visual:
+ * @widget: a #GtkWidget
+ * @visual: visual to be used or %NULL to unset a previous one
+ * 
+ * Sets the visual that should be used for by widget and its children for
+ * creating #GdkWindows. The visual must be on the same #GdkScreen as
+ * returned by gdk_widget_get_screen(), so handling the
+ * GtkWidget::screen-changed signal is necessary.
+ *
+ * Setting a new @visual will not cause @widget to recreate its windows,
+ * so you should call this function before @widget is realized.
+ **/
+void
+gtk_widget_set_visual (GtkWidget *widget,
+                       GdkVisual *visual)
+{
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (visual == NULL || GDK_IS_VISUAL (visual));
+  if (visual)
+    {
+      g_return_if_fail (gtk_widget_get_screen (widget) == gdk_visual_get_screen (visual));
+    }
+
+  g_object_set_qdata_full (G_OBJECT (widget), 
+                           quark_visual,
+                           g_object_ref (visual),
+                           g_object_unref);
+}
+
 /**
  * gtk_widget_get_visual:
  * @widget: a #GtkWidget
@@ -8967,20 +8999,31 @@ GdkVisual*
 gtk_widget_get_visual (GtkWidget *widget)
 {
   GtkWidget *w;
+  GdkVisual *visual;
+  GdkScreen *screen;
 
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
+  if (gtk_widget_get_has_window (widget) &&
+      widget->priv->window)
+    return gdk_window_get_visual (widget->priv->window);
+
+  screen = gtk_widget_get_screen (widget);
+
   for (w = widget; w != NULL; w = w->priv->parent)
     {
-      if (gtk_widget_get_has_window (w) &&
-          w->priv->window)
-        return gdk_window_get_visual (w->priv->window);
+      visual = g_object_get_qdata (G_OBJECT (w), quark_visual);
+      if (visual)
+        {
+          if (gdk_visual_get_screen (visual) == screen)
+            return visual;
 
-      if (GTK_IS_WINDOW (w))
-        return _gtk_window_get_visual (GTK_WINDOW (w));
+          g_warning ("Ignoring visual set on widget `%s' that is not on the correct screen.",
+                     gtk_widget_get_name (widget));
+        }
     }
 
-  return gdk_screen_get_system_visual (gdk_screen_get_default ());
+  return gdk_screen_get_system_visual (screen);
 }
 
 /**
index 457b2abe9aab8e01ea45e687f2bb917616d25f77..c94dd6a005fb573ed01da0d0fe52a417c8b19bbb 100644 (file)
@@ -634,6 +634,8 @@ GtkWidget*   gtk_widget_get_toplevel        (GtkWidget      *widget);
 GtkWidget*   gtk_widget_get_ancestor   (GtkWidget      *widget,
                                         GType           widget_type);
 GdkVisual*   gtk_widget_get_visual     (GtkWidget      *widget);
+void         gtk_widget_set_visual     (GtkWidget      *widget,
+                                         GdkVisual      *visual);
 
 GdkScreen *   gtk_widget_get_screen      (GtkWidget *widget);
 gboolean      gtk_widget_has_screen      (GtkWidget *widget);